


* Table 1: Summary statistics
use "campaign day dataset.dta", clear
eststo clear
eststo: quietly estpost summarize daily_usd update ///
        pos_roberta neg_roberta uncertain_roberta total_roberta hhi goal_reached mile0
esttab, cells("mean(fmt(2)) sd(fmt(2)) min(fmt(2)) max(fmt(2))") varwidth(56) ///
        title(Table 1: Summary statistics) nonumbers noobs ///
        refcat(pos_roberta "Backer comments:") ///
		coeflabels(daily_usd "Daily pledge (USD)" ///
        neg_roberta "- Negative sentiment score" ///
        pos_roberta "- Positive sentiment score" ///
		uncertain_roberta "- Uncertainty score" ///
		total_roberta "- Total number of words" ///
		update "Campaign update (binary)" goal_reached "Funding goal reached (binary)" ///
		mile0 "Funding milestone (binary)" hhi "- Homogeneity of topics (Herfindahl-Hirschman index)") ///
		addnotes("N = 5,908 (175 campaigns, up to 63 campaign days).")

quietly pwcorr daily_usd update ///
        pos_roberta neg_roberta uncertain_roberta total_roberta hhi goal_reached mile0, star (0.05)
matrix list r(C), format(%4.2f)




* Table 2: Regression results
use "campaign day dataset.dta", clear
quietly tabulate day, gen(day_dummy_)

eststo clear
* uncertainty
quietly eststo: reg d.uncertain_roberta d.update d.total_roberta d.hhi ///
 dl(1/1).uncertain_roberta d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
* updates > sentiment
quietly eststo: reg d.pos_roberta d.update d.total_roberta d.hhi ///
 dl(1/1).pos_roberta d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
quietly eststo: reg d.neg_roberta d.update d.total_roberta d.hhi ///
 dl(1/1).neg_roberta d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
* updates > funding
quietly eststo: reg d.daily_usd d.update ///
 dl(1/1).daily_usd d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
* sentiment > funding
quietly eststo: reg d.daily_usd d.neg_roberta d.pos_roberta d.total_roberta d.hhi ///
 dl(1/1).daily_usd d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
lincom D1.pos_roberta+ D1.neg_roberta
* updates + sentiment > funding
quietly eststo: reg d.daily_usd d.update d.neg_roberta d.pos_roberta d.total_roberta d.hhi ///
 dl(1/1).daily_usd d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
esttab, star(* 0.10 ** 0.05 *** 0.01) se compress nonotes varwidth(30) noobs ///
 cells(b(fmt(2) star) se(par fmt(2))) modelwidth(13) ///
 scalars("r2_a Adj. R^2" "N Observations") sfmt(3 0) ///
 refcat(D.pos_roberta "Backer comments:" LD.uncertain_roberta "Backer comments (previous day):") ///
 order(D.update D.pos_roberta D.neg_roberta D.total_roberta D.hhi ///
 D.goal_reached D.mile0 LD.daily_usd LD.uncertain_roberta LD.pos_roberta LD.neg_roberta) ///
 coeflabels(D.update "Campaign update" D.pos_roberta "- Positive sentiment score" ///
 D.neg_roberta "- Negative sentiment score" D.total_roberta "- Total number of words" ///
 D.hhi "- Homogeneity of topics" D.goal_reached "Funding goal reached" D.mile0 "Funding milestone" ///
 LD.daily_usd "Daily pledge (previous day)" LD.pos_roberta "- Positive sentiment score" ///
 LD.neg_roberta "- Negative sentiment score" LD.uncertain_roberta "- Uncertainty score") ///
 title(Table 2: Regression results) ///
 drop(*day_dummy*) ///
 mgroups("Backer comments:", pattern(1 0 0 0 0 0)) ///
 mtitles("Uncertainty" "Positive" "Negative" ///
 "Daily pledge (USD)" "Daily pledge (USD)" "Daily pledge (USD)") ///
 addnotes("Notes: OLS estimates with variables in first differences. All models include day-of-campaign dummies (output omitted). Standard errors (in parentheses) are clustered by campaign." ///
 "* p<0.10, ** p<0.05, *** p<0.01") 
 
 
 

* Table A3: Granger causality tests between pairs of key variables
use "campaign day dataset.dta", clear
xtset running_id day 

rename uncertain_roberta unc
quietly pvar unc update, lags(2)
pvargranger 
 
quietly pvar pos_roberta update, lags(2)
pvargranger 
 
quietly pvar neg_roberta update, lags(2)
pvargranger
 
quietly pvar daily_usd update, lags(2)
pvargranger 
 
 
 
 
* Table A4: Regression results (restricted to observations prior to March 11, 2020)
use "campaign day dataset.dta", clear
* drop observations after declaration of pandemic by WHO (19 campaigns left)
keep if date < td(11.03.2020)

* omit day dummies due to low number of observations
* do not cluster standard errors due to low number of clusters
eststo clear
* uncertainty
quietly eststo: reg d.uncertain_roberta d.update d.total_roberta d.hhi ///
 dl(1/1).uncertain_roberta d.mile0 d.goal_reached, nocons robust
* updates > sentiment
quietly eststo: reg d.pos_roberta d.update d.total_roberta d.hhi ///
 dl(1/1).pos_roberta d.mile0 d.goal_reached, nocons robust
quietly eststo: reg d.neg_roberta d.update d.total_roberta d.hhi ///
 dl(1/1).neg_roberta d.mile0 d.goal_reached, nocons robust
* updates > funding
quietly eststo: reg d.daily_usd d.update ///
 dl(1/1).daily_usd d.mile0 d.goal_reached, nocons robust
* sentiment > funding
quietly eststo: reg d.daily_usd d.neg_roberta d.pos_roberta d.total_roberta d.hhi ///
 dl(1/1).daily_usd d.mile0 d.goal_reached, nocons robust
lincom D1.pos_roberta+ D1.neg_roberta
* updates + sentiment > funding
quietly eststo: reg d.daily_usd d.update d.neg_roberta d.pos_roberta d.total_roberta d.hhi ///
 dl(1/1).daily_usd d.mile0 d.goal_reached, nocons robust
esttab, star(* 0.10 ** 0.05 *** 0.01) se compress nonotes varwidth(30) noobs ///
 cells(b(fmt(2) star) se(par fmt(2))) modelwidth(13) ///
 scalars("r2_a Adj. R^2" "N Observations") sfmt(3 0) ///
 refcat(D.pos_roberta "Backer comments:" LD.uncertain_roberta "Backer comments (previous day):") ///
 order(D.update D.pos_roberta D.neg_roberta D.total_roberta D.hhi ///
 D.goal_reached D.mile0 LD.daily_usd LD.uncertain_roberta LD.pos_roberta LD.neg_roberta) ///
 coeflabels(D.update "Campaign update" D.pos_roberta "- Positive sentiment score" ///
 D.neg_roberta "- Negative sentiment score" D.total_roberta "- Total number of words" ///
 D.hhi "- Homogeneity of topics" D.goal_reached "Funding goal reached" D.mile0 "Funding milestone" ///
 LD.daily_usd "Daily pledge (previous day)" LD.pos_roberta "- Positive sentiment score" ///
 LD.neg_roberta "- Negative sentiment score" LD.uncertain_roberta "- Uncertainty score") ///
 title(Table A4: Regression results (restricted to observations prior to March 11, 2020)) ///
 mgroups("Backer comments:", pattern(1 0 0 0 0 0)) ///
 mtitles("Uncertainty" "Positive" "Negative" ///
 "Daily pledge (USD)" "Daily pledge (USD)" "Daily pledge (USD)") ///
 addnotes("Notes: OLS estimates with variables in first differences. In contrast to the baseline specification, the relatively low number of observations in the pre-Covid sample prevents us from including day-of-campaign dummy variables here. We also refrain from clustering standard errors by campaign – since we observe only 19 campaigns before the onset of the pandemic – but report heteroscedasticity-robust standard errors (in parentheses) instead." ///
 "* p<0.10, ** p<0.05, *** p<0.01") 
 
 
 
 

 
 * Table A5: Regression results based on bag-of-words measures of uncertainty and sentiment
use "campaign day dataset.dta", clear
quietly tabulate day, gen(day_dummy_)

eststo clear
* uncertainty
quietly eststo: reg d.uncertainty d.update d.total_words_ordinary d.hhi ///
 dl(1/1).uncertainty d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
* updates > sentiment
quietly eststo: reg d.pos_ordinary d.update d.total_words_ordinary d.hhi ///
 dl(1/1).pos_ordinary d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
quietly eststo: reg d.neg_ordinary d.update d.total_words_ordinary d.hhi ///
 dl(1/1).neg_ordinary d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
* updates > funding
quietly eststo: reg d.daily_usd d.update ///
 dl(1/1).daily_usd d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
* sentiment > funding
quietly eststo: reg d.daily_usd d.neg_ordinary d.pos_ordinary d.total_words_ordinary d.hhi ///
 dl(1/1).daily_usd d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
lincom D1.pos_ordinary+ D1.neg_ordinary
* updates + sentiment > funding
quietly eststo: reg d.daily_usd d.update d.neg_ordinary d.pos_ordinary d.total_words_ordinary d.hhi ///
 dl(1/1).daily_usd d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
esttab, star(* 0.10 ** 0.05 *** 0.01) se compress nonotes varwidth(30) noobs ///
 cells(b(fmt(2) star) se(par fmt(2))) modelwidth(13) ///
 scalars("r2_a Adj. R^2" "N Observations") sfmt(3 0) ///
 title(Table A5: Regression results based on bag-of-words measures of uncertainty and sentiment) ///
 refcat(D.pos_ordinary "Backer comments:" LD.uncertainty "Backer comments (previous day):") ///
 order(D.update D.pos_ordinary D.neg_ordinary D.total_words_ordinary D.hhi ///
 D.goal_reached D.mile0 LD.daily_usd LD.uncertainty LD.pos_ordinary LD.neg_ordinary) ///
 coeflabels(D.update "Campaign update" D.pos_ordinary "- Positive sentiment score" ///
 D.neg_ordinary "- Negative sentiment score" D.total_words_ordinary "- Total number of words" ///
 D.hhi "- Homogeneity of topics" D.goal_reached "Funding goal reached" D.mile0 "Funding milestone" ///
 LD.daily_usd "Daily pledge (previous day)" LD.pos_ordinary "- Positive sentiment score" ///
 LD.neg_ordinary "- Negative sentiment score" LD.uncertainty "- Uncertainty score") ///
 drop(*day_dummy*) ///
 mgroups("Backer comments:", pattern(1 0 0 0 0 0)) ///
 mtitles("Uncertainty" "Positive" "Negative" ///
 "Daily pledge (USD)" "Daily pledge (USD)" "Daily pledge (USD)") ///
 addnotes("Notes: OLS estimates with variables in first differences. All models include day-of-campaign dummies (output omitted). Standard errors (in parentheses) are clustered by campaign. In contrast to the baseline specification in Table 2, the regressions use dictionary-based measures of uncertainty and sentiment. That is, positive sentiment score and negative sentiment score are counts of relevant words listed in the English version of the NRC Sentiment Lexicon (Mohammad & Turney, 2013). Uncertainty score counts the number of words listed in a dictionary of 242 uncertainly-expressions derived from the WikiWeasel corpus (Farkas et al., 2010; Vincze, 2013)." ///
 "* p<0.10, ** p<0.05, *** p<0.01")

 
 
 
 
  
 
 
 
**************************
* Update characteristics *
**************************
 
* 1) many gaps: many update texts are non-public; missing data in Wayback Machine
* 2) update content not observed on days without any update
* --> few observations; does not work in first differences due to gaps
 
use "campaign day dataset.dta", clear
quietly tabulate day, gen(day_dummy_)

*Table A6: Regression results with updates' number of words
eststo clear
* uncertainty
quietly eststo: reg uncertain_roberta updates_words total_roberta ///
 l(1/1).uncertain_roberta day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
* updates > sentiment
quietly eststo: reg pos_roberta updates_words total_roberta ///
 l(1/1).pos_roberta day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
quietly eststo: reg neg_roberta updates_words total_roberta ///
 l(1/1).neg_roberta day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
* updates > funding
quietly eststo: reg daily_usd updates_words ///
 l(1/1).daily_usd day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
esttab, star(* 0.10 ** 0.05 *** 0.01) se compress nonotes varwidth(30) noobs ///
 cells(b(fmt(2) star) se(par fmt(2))) modelwidth(13) ///
 scalars("r2_a Adj. R^2" "N Observations") sfmt(3 0) ///
 refcat(total_roberta "Backer comments:" L.uncertain_roberta "Backer comments (previous day):") ///
 order(updates_words total_roberta hhi ///
 goal_reached mile0 L.daily_usd L.uncertain_roberta L.pos_roberta L.neg_roberta) ///
 coeflabels(updates_words "Updates: number of words" total_roberta "- Total number of words" ///
 hhi "- Homogeneity of topics" goal_reached "Funding goal reached" mile0 "Funding milestone" ///
 L.daily_usd "Daily pledge (previous day)" L.pos_roberta "- Positive sentiment score" ///
 L.neg_roberta "- Negative sentiment score" L.uncertain_roberta "- Uncertainty score") ///
 title(Table A6: Regression results with updates' number of words) ///
 drop(*day_dummy*) ///
 mgroups("Backer comments:", pattern(1 0 0 0)) ///
 mtitles("Uncertainty" "Positive" "Negative" "Daily pledge (USD)") ///
 addnotes("Notes: OLS estimates. The regressions use a subset of the analysis sample where update texts are available. All models include day-of-campaign dummies (output omitted). Standard errors (in parentheses) are clustered by campaign." ///
 "* p<0.10, ** p<0.05, *** p<0.01") 
 
 
* Table A7: Regression results with updates' readability
eststo clear
* uncertainty
quietly eststo: reg uncertain_roberta updates_read total_roberta ///
 l(1/1).uncertain_roberta day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
* updates > sentiment
quietly eststo: reg pos_roberta updates_read total_roberta ///
 l(1/1).pos_roberta day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
quietly eststo: reg neg_roberta updates_read total_roberta ///
 l(1/1).neg_roberta day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
* updates > funding
quietly eststo: reg daily_usd updates_read ///
 l(1/1).daily_usd day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
esttab, star(* 0.10 ** 0.05 *** 0.01) se compress nonotes varwidth(30) noobs ///
 cells(b(fmt(2) star) se(par fmt(2))) modelwidth(13) ///
 scalars("r2_a Adj. R^2" "N Observations") sfmt(3 0) ///
 refcat(total_roberta "Backer comments:" L.uncertain_roberta "Backer comments (previous day):") ///
 order(updates_read total_roberta hhi ///
 goal_reached mile0 L.daily_usd L.uncertain_roberta L.pos_roberta L.neg_roberta) ///
 coeflabels(updates_read "Updates: readability" total_roberta "- Total number of words" ///
 hhi "- Homogeneity of topics" goal_reached "Funding goal reached" mile0 "Funding milestone" ///
 L.daily_usd "Daily pledge (previous day)" L.pos_roberta "- Positive sentiment score" ///
 L.neg_roberta "- Negative sentiment score" L.uncertain_roberta "- Uncertainty score") ///
 title(Table A7: Regression results with updates' readability) ///
 drop(*day_dummy*) ///
 mgroups("Backer comments:", pattern(1 0 0 0)) ///
 mtitles("Uncertainty" "Positive" "Negative" "Daily pledge (USD)") ///
 addnotes("Notes: OLS estimates. The regressions use a subset of the analysis sample where update texts are available. Readability is measured as Flesch's Reading Ease Score. All models include day-of-campaign dummies (output omitted). Standard errors (in parentheses) are clustered by campaign." ///
 "* p<0.10, ** p<0.05, *** p<0.01") 
 
 
* Table A8: Regression results with updates' lexical diversity
eststo clear
* uncertainty
quietly eststo: reg uncertain_roberta updates_lexdiv total_roberta ///
 l(1/1).uncertain_roberta day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
* updates > sentiment
quietly eststo: reg pos_roberta updates_lexdiv total_roberta ///
 l(1/1).pos_roberta day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
quietly eststo: reg neg_roberta updates_lexdiv total_roberta ///
 l(1/1).neg_roberta day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
* updates > funding
quietly eststo: reg daily_usd updates_lexdiv ///
 l(1/1).daily_usd day_dummy* mile0 goal_reached hhi, nocons cluster(running_id)
esttab, star(* 0.10 ** 0.05 *** 0.01) se compress nonotes varwidth(30) noobs ///
 cells(b(fmt(2) star) se(par fmt(2))) modelwidth(13) ///
 scalars("r2_a Adj. R^2" "N Observations") sfmt(3 0) ///
 refcat(total_roberta "Backer comments:" L.uncertain_roberta "Backer comments (previous day):") ///
 order(updates_lexdiv total_roberta hhi ///
 goal_reached mile0 L.daily_usd L.uncertain_roberta L.pos_roberta L.neg_roberta) ///
 coeflabels(updates_lexdiv "Updates: lexical diversity" total_roberta "- Total number of words" ///
 hhi "- Homogeneity of topics" goal_reached "Funding goal reached" mile0 "Funding milestone" ///
 L.daily_usd "Daily pledge (previous day)" L.pos_roberta "- Positive sentiment score" ///
 L.neg_roberta "- Negative sentiment score" L.uncertain_roberta "- Uncertainty score") ///
 title(Table A8: Regression results with updates' lexical diversity) ///
 drop(*day_dummy*) ///
 mgroups("Backer comments:", pattern(1 0 0 0)) ///
 mtitles("Uncertainty" "Positive" "Negative" "Daily pledge (USD)") ///
 addnotes("Notes: OLS estimates. The regressions use a subset of the analysis sample where update texts are available. Lexical diversity is measured as the ratio of unique words to all words. All models include day-of-campaign dummies (output omitted). Standard errors (in parentheses) are clustered by campaign." ///
 "* p<0.10, ** p<0.05, *** p<0.01") 
 
 
 
 
 
 

* Figure A2: Tests for differences by location of campaign (reference group: North America)
use "campaign day dataset.dta", clear
quietly tabulate day, gen(day_dummy_)

* cannot run by individual country (because some countries only one or few campaigns),
* but split region (North America, Europe, Asia) --> no meaningful differences
gen d_update = d.update

* A: Uncertainty
quietly reg d.uncertain_roberta c.d_update##i.region d.total_roberta d.hhi ///
 dl(1/1).uncertain_roberta d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
est sto w
coefplot w, vert keep(2.region#c.d_update 3.region#c.d_update) base scheme(s2mono) msymbol(O) msize(small) ciopt(lcolor(gs8)) ///
 levels(95) mcolor(black) legend(off) graphregion(color(white)) ///
 yline(0) ylabel(-20(10)20, angle(0) gmin gmax) ///
 ytitle("Coefficient values") scale(1.7) aspect(0.9) ///
 xlabel(1 "Europe" 2 "Asia/Oceania")
* B: Positive sentiment
quietly reg d.pos_roberta c.d_update##i.region d.total_roberta d.hhi ///
 dl(1/1).pos_roberta d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
est sto w
coefplot w, vert keep(2.region#c.d_update 3.region#c.d_update) base scheme(s2mono) msymbol(O) msize(small) ciopt(lcolor(gs8)) ///
 levels(95) mcolor(black) legend(off) graphregion(color(white)) ///
 yline(0) ylabel(-20(10)20, angle(0) gmin gmax) omitted ///
 ytitle("Coefficient values") scale(1.7) aspect(0.9) ///
 xlabel(1 "Europe" 2 "Asia/Oceania")
* C: Negative sentiment
quietly reg d.neg_roberta c.d_update##i.region d.total_roberta d.hhi ///
 dl(1/1).neg_roberta d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id) 
est sto w
coefplot w, vert keep(2.region#c.d_update 3.region#c.d_update) base scheme(s2mono) msymbol(O) msize(small) ciopt(lcolor(gs8)) ///
 levels(95) mcolor(black) legend(off) graphregion(color(white)) ///
 yline(0) ylabel(-20(10)20, angle(0) gmin gmax) omitted ///
 ytitle("Coefficient values") scale(1.7) aspect(0.9) ///
 xlabel(1 "Europe" 2 "Asia/Oceania")
* D: Funding
quietly reg d.daily_usd c.d_update##i.region ///
 dl(1/1).daily_usd d.day_dummy* d.mile0 d.goal_reached, nocons cluster(running_id)
est sto w
coefplot w, vert keep(2.region#c.d_update 3.region#c.d_update) base scheme(s2mono) msymbol(O) msize(small) ciopt(lcolor(gs8)) ///
 levels(95) mcolor(black) legend(off) graphregion(color(white)) ///
 yline(0) ylabel(-2000(1000)2000, angle(0) gmin gmax) omitted ///
 ytitle("Coefficient values") scale(1.7) aspect(0.9) ///
 xlabel(1 "Europe" 2 "Asia/Oceania")

 
 
 
 
 
 
 
 
 
 

